const cases_detail: any = Object.freeze({
    [Etypedetail.undefined]: [UNDEFINED],
    [Etypedetail.symbol]: [Symbol(), Symbol(UNDEFINED), Symbol(0), Symbol('foo')],

    [Etypedetail.bigint_zero]: [BigInt0],
    [Etypedetail.bigint_positive]: [BigInt(333333333)],
    [Etypedetail.bigint_negative]: [BigInt(-333333333)],

    [Etypedetail.number_NaN]: [NaN],
    [Etypedetail.number_positive_Infinity]: [Infinity],
    [Etypedetail.number_negative_Infinity]: [-Infinity],
    [Etypedetail.number_zero]: [0, -0],
    [Etypedetail.number_positive_Integer]: [3],
    [Etypedetail.number_negative_Integer]: [-3],
    [Etypedetail.number_positive_Decimal]: [3.3],
    [Etypedetail.number_negative_Decimal]: [-3.3],

    [Etypedetail.boolean_true]: [true],
    [Etypedetail.boolean_false]: [false],

    [Etypedetail.string_empty]: [''],
    [Etypedetail.string_blank]: [' ', '   '],
    [Etypedetail.string]: ['foo', ' bar ', ' q u x ', '0'],

    [Etypedetail.function]: [
        () => { },
        function () { },
    ],

    [Etypedetail.null]: [null],

    [Etypedetail.DEFAULT]: [DEFAULT],

    [Etypedetail.NULLOBJ]: [Object.create(null)],

    [Etypedetail.obj_empty]: [
        {},
        // Object.create创建的对象属性默认是不可枚举的
        Object.create({ x: 'foo', y: ' bar ', z: ' q u x ' })
    ],
    [Etypedetail.obj]: [
        { x: 'foo', y: ' bar ', z: ' q u x ' },
        // Object.create创建的对象属性默认是不可枚举的，创建可枚举属性需要额外传值。
        Object.create({}, { x: { value: 'foo', enumerable: true }, y: { value: ' bar ', enumerable: true }, z: { value: ' q u x ', enumerable: true } })
    ],

    [Etypedetail.array_empty]: [[]],
    [Etypedetail.array]: [['foo', ' bar ', ' q u x '], [11, 22, 33]],

    // HTMLElement子类会会断增加，无法准确定义。也使用字符串。
    ['HTMLHeadElement']: [document.head],
    ['HTMLScriptElement']: [document.head.querySelector('script')],

    ['[object KHTMLElement]']: [new KHTMLElement(document.head), new KHTMLElement(document.head.querySelectorAll('script'))],

    // 其它类型，不需要定义，使用字符串。
    ['[object NodeList]']: [document.head.querySelectorAll('script')],
    ['[object Map]']: [new Map(), new Map().set('x', 'foo').set('y', ' bar ').set('z', ' q u x ')],
    ['[object Set]']: [new Set(), new Set(['foo', ' bar ', ' q u x ']), new Set([11, 22, 33])],
    ['[object WeakMap]']: [new WeakMap()],
    ['[object RegExp]']: [new RegExp(''), /foo/],
});

const cases: { [key: string]: Array<string> } = {};

cases[Etype.undefined] = []
    .concat(cases_detail[Etypedetail.undefined]);
cases[Etype.symbol] = []
    .concat(cases_detail[Etypedetail.symbol]);

cases[Etype.bigint] = []
    .concat(cases_detail[Etypedetail.bigint_zero])
    .concat(cases_detail[Etypedetail.bigint_positive])
    .concat(cases_detail[Etypedetail.bigint_negative]);

cases[Etype.number] = []
    .concat(cases_detail[Etypedetail.number_zero])
    .concat(cases_detail[Etypedetail.number_NaN])
    .concat(cases_detail[Etypedetail.number_positive_Infinity])
    .concat(cases_detail[Etypedetail.number_negative_Infinity])
    .concat(cases_detail[Etypedetail.number_positive_Integer])
    .concat(cases_detail[Etypedetail.number_negative_Integer])
    .concat(cases_detail[Etypedetail.number_positive_Decimal])
    .concat(cases_detail[Etypedetail.number_negative_Decimal]);

cases[Etype.boolean] = []
    .concat(cases_detail[Etypedetail.boolean_true])
    .concat(cases_detail[Etypedetail.boolean_false]);

cases[Etype.string] = []
    .concat(cases_detail[Etypedetail.string_empty])
    .concat(cases_detail[Etypedetail.string_blank])
    .concat(cases_detail[Etypedetail.string]);

cases[Etype.function] = []
    .concat(cases_detail[Etypedetail.function]);

cases[Etype.null] = []
    .concat(cases_detail[Etypedetail.null]);

cases[Etype.NULLOBJ] = []
    .concat(cases_detail[Etypedetail.NULLOBJ]);

cases[Etype.DEFAULT] = []
    .concat(cases_detail[Etypedetail.DEFAULT]);

cases[Etype.obj] = []
    .concat(cases_detail[Etypedetail.obj_empty])
    .concat(cases_detail[Etypedetail.obj])
    ;

cases[Etype.array] = []
    .concat(cases_detail[Etypedetail.array_empty])
    .concat(cases_detail[Etypedetail.array]);

cases[Etype.HTMLElement] = []
    .concat(cases_detail['HTMLHeadElement'])
    .concat(cases_detail['HTMLScriptElement']);

cases[Etype.KHTMLElement] = []
    .concat(cases_detail['[object KHTMLElement]']);

cases[Etype.NodeList] = []
    .concat(cases_detail['[object NodeList]']);

cases[Etype.Map] = []
    .concat(cases_detail['[object Map]']);

cases[Etype.Set] = []
    .concat(cases_detail['[object Set]']);

cases[Etype.WeakMap] = []
    .concat(cases_detail['[object WeakMap]']);

cases[Etype.RegExp] = []
    .concat(cases_detail['[object RegExp]']);

Object.freeze(cases);

const loopCases = (fn: (key1: string, i: number, value1: any) => void, casesObj?: any) => {
    casesObj = casesObj || cases;
    for (const key1 in casesObj) {
        if (Object.prototype.hasOwnProperty.call(casesObj, key1)) {
            const typeCases1 = casesObj[key1];
            for (let i = 0; i < typeCases1.length; i++) {
                const value1 = typeCases1[i];
                fn(key1, i, value1);
            }
        }
    }
};
